//
//  TEST_ClientProtocol.m
//  TEST_NSURLProtocol
//
//  Created by lianglibao on 2019/3/11.
//  Copyright © 2019年 lianglibao. All rights reserved.
//

#import "TEST_ClientProtocol.h"
static NSString * const URLProtocolHandledKey = @"URLProtocolHandledKey";

@interface TEST_ClientProtocol () <NSURLSessionTaskDelegate>
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSURLSessionTask *task;
@end

@implementation TEST_ClientProtocol

- (NSURLSession *)session {
    if (!_session) {
        NSURLSessionConfiguration *congfig = [NSURLSessionConfiguration defaultSessionConfiguration];
        _session = [NSURLSession sessionWithConfiguration:congfig
                                                 delegate:self
                                            delegateQueue:[[NSOperationQueue alloc] init]];
    }
    return _session;
}


// MARK: - overwrite method

+ (BOOL)canInitWithRequest:(NSURLRequest *)request{
    NSLog(@"canInitWithRequest url-->%@",request.URL.absoluteString);
    
    //看看是否已经处理过了，防止无限循环
    if ([self.class propertyForKey:URLProtocolHandledKey inRequest:request]) {
        return NO;
    }
    
    NSString *urlString = request.URL.absoluteString;
    if([urlString containsString:@"https://sina.cn"]){
        return YES;
    }
    
    return YES;
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
    return request;
}

- (void)startLoading{
    
    NSMutableURLRequest * request = [self.request mutableCopy];
    
    // 标记当前传入的Request已经被拦截处理过，
    //防止在最开始又继续拦截处理
    [self.class setProperty:@(YES) forKey:URLProtocolHandledKey inRequest:request];
    
    self.task = [self.session dataTaskWithRequest:[self changeRequest:request]];
    [self.task resume];
}

- (void)stopLoading {
    [self.task cancel];
    self.task = nil;
    [self.session invalidateAndCancel];
    //self.session = nil;
}

// MARK: - NSURLSessionTaskDelegate

//把所用url中包括sina的url重定向到百度
- (NSMutableURLRequest *)changeRequest:(NSMutableURLRequest *)request{
    NSString *urlString = request.URL.absoluteString;
    if ([urlString isEqualToString:@"https://sina.cn/"]) {
        urlString = @"https://taobao.com";
        request.URL = [NSURL URLWithString:urlString];
    }
    return request;
}

/* The task has received a response and no further messages will be
 * received until the completion block is called. The disposition
 * allows you to cancel a request or to turn a data task into a
 * download task. This delegate message is optional - if you do not
 * implement it, you can get the response as a property of the task.
 *
 * This method will not be called for background upload tasks (which cannot be converted to download tasks).
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
 completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
    completionHandler(NSURLSessionResponseAllow);
}

/* Sent when data is available for the delegate to consume.  It is
 * assumed that the delegate will retain and not copy the data.  As
 * the data may be discontiguous, you should use
 * [NSData enumerateByteRangesUsingBlock:] to access it.
 */
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
    didReceiveData:(NSData *)data {
    [self.client URLProtocol:self didLoadData:data];
}

/* Sent as the last message related to a specific task.  Error may be
 * nil, which implies that no error occurred and this task is complete.
 */
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error {
    if (error) {
        [self.client URLProtocol:self didFailWithError:error];
    } else {
        [self.client URLProtocolDidFinishLoading:self];
    }
}


@end
